package cn.lijiajia3515.cairo.auth.modules.account;

import cn.lijiajia3515.cairo.core.page.Page;
import cn.lijiajia3515.cairo.security.oauth2.jwt.CairoJwtPrincipal;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.security.PermitAll;
import java.util.List;
import java.util.Optional;

/**
 * 账号 api
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/api/account")
public class AccountApi {

	private final AccountService accountService;

	public AccountApi(AccountService accountService) {
		this.accountService = accountService;
	}

	/**
	 * 注册
	 *
	 * @param param 参数
	 * @return 账号
	 */
	@PostMapping("/reg")
	@PermitAll
	public Account reg(@RequestBody @Validated SaveAccountParam param) {
		return accountService.reg(param);
	}

	/**
	 * 新增账号
	 *
	 * @param param 参数
	 * @return 账号
	 */
	@PostMapping("/save")
	@PreAuthorize("hasAnyAuthority('scp_save:account')")
	public Account save(@AuthenticationPrincipal CairoJwtPrincipal principal, @RequestBody @Validated SaveAccountParam param) {
		return accountService.save(principal.getAppId(), param);
	}

	/**
	 * 修改账号
	 *
	 * @param param 参数
	 * @return 账号
	 */
	@PutMapping("/modify")
	@PreAuthorize("hasAnyAuthority('scp_modify:account')")
	public Account modify(@AuthenticationPrincipal CairoJwtPrincipal principal, @RequestBody @Validated ModifyAccountParam param) {
		return accountService.modify(principal.getAppId(), param).orElseThrow();
	}

	/**
	 * 重置 密码
	 *
	 * @param principal 当前用户
	 * @param param     参数
	 * @return 新密码
	 */
	@PatchMapping("/password_reset")
	@PreAuthorize("hasAnyAuthority('scp_reset_password:account')")
	public Optional<String> passwordReset(@AuthenticationPrincipal CairoJwtPrincipal principal, @RequestBody @Validated ResetPasswordAccountParam param) {
		return accountService.resetPassword(principal.getAppId(), param);
	}

	/**
	 * 状态修改
	 *
	 * @param principal 当前用户
	 * @param param     修改参数
	 * @return 修改结果
	 */
	@PatchMapping("/status_modify")
	@PreAuthorize("hasAnyAuthority('scp_modify_status:account')")
	public Optional<Boolean> modifyStatus(@AuthenticationPrincipal CairoJwtPrincipal principal, @RequestBody @Validated ModifyStatusAccountParam param) {
		return accountService.modifyStatus(principal.getAppId(), param);
	}

	/**
	 * 分页查询 账号
	 *
	 * @param principal 当前用户
	 * @param param     查询参数
	 * @return 账号 列表
	 */
	@PostMapping("/find")
	@PreAuthorize("hasAnyAuthority('scp_find:account')")
	public List<Account> find(@AuthenticationPrincipal CairoJwtPrincipal principal,
							  @RequestBody(required = false) @Validated FindAccountParam param) {
		return accountService.find(principal.getAppId(), param);
	}

	/**
	 * 分页查询
	 *
	 * @param principal 当前用户
	 * @param param     查询参数
	 * @return 分页 账号
	 */
	@PostMapping("/find_page")
	@PreAuthorize("hasAnyAuthority('scp_find:account')")
	public Page<Account> findPage(@AuthenticationPrincipal CairoJwtPrincipal principal,
								  @RequestBody(required = false) @Validated FindAccountParam param) {
		return accountService.findPage(principal.getAppId(), param);
	}

	/**
	 * 单个账号查询
	 *
	 * @param principal 当前用户
	 * @param id        id
	 * @return 账号
	 */
	@GetMapping("/find/{id}")
	@PreAuthorize("hasAnyAuthority('scp_find:account')")
	public Account findById(@AuthenticationPrincipal CairoJwtPrincipal principal, @PathVariable String id) {
		return accountService.findById(principal.getAppId(), id).orElseThrow();
	}

	/**
	 * 当前用户 密码修改
	 *
	 * @param principal 当前用户
	 * @param param     参数
	 */
	@PatchMapping("/my_password_modify")
	@PreAuthorize("hasAuthority('account')")
	public void modifyPassword(@AuthenticationPrincipal CairoJwtPrincipal principal, @RequestBody @Validated ModifyPasswordAccountParam param) {
		accountService.modifyPassword(principal.getAzp(), principal.getAccount().getId(), param);
	}

	/**
	 * 当前用户修改
	 *
	 * @param principal 认证用户信息
	 * @param param     参数
	 */
	@PatchMapping("/my_modify")
	@PreAuthorize("hasAnyAuthority('account')")
	public void currentModify(@AuthenticationPrincipal CairoJwtPrincipal principal, @RequestBody @Validated ModifyCurrentAccountParam param) {
		accountService.modify(principal.getAzp(), param);
	}
}
